Skip to content

Tracking PR for v0.23.0 release#2878

Draft
bobbinth wants to merge 145 commits intomainfrom
next
Draft

Tracking PR for v0.23.0 release#2878
bobbinth wants to merge 145 commits intomainfrom
next

Conversation

@bobbinth
Copy link
Copy Markdown
Contributor

This is a tracking PR for v0.23.0 release

crazywriter1 and others added 30 commits March 18, 2026 16:10
…in Meta::from_iter (#2870)

Co-authored-by: crazywriter1 <crazywriter1@users.noreply.github.com>
Co-authored-by: François Garillot <4142+huitseeker@users.noreply.github.com>
chore(processor): remove `NodeEndFlags` from `NodeEndData`
Co-authored-by: François Garillot <4142+huitseeker@users.noreply.github.com>
)

* test(processor): cover nested loop end flags across fragmentation

* test: document trace clock-by-clock
…ation in define_enum (#2887)

* fix(assembly-syntax): validate C-like enums by removing early return in define_enum

* chore: add changelog entry for C-like enum fix

---------

Co-authored-by: crazywriter1 <crazywriter1@users.noreply.github.com>
Co-authored-by: François Garillot <4142+huitseeker@users.noreply.github.com>
…check

fix(assembly): correct cycle detection in toposort_caller
… (#2908)

The change in #2893 incorrectly used InvokeKind::ProcRef. The original
InvokeKind::Exec was intentional: a procref instruction captures a
procedure reference for later invocation, and we must pessimistically
assume it will be invoked. Exec is the most general invocation kind
and the linker needs this signal to correctly track dependencies.

Added an explanatory comment so this does not get changed again.

Reported by @bitwalker, confirmed by @bobbinth.

Co-authored-by: amathxbt <amathxbt@users.noreply.github.com>
…ibility (#2865)

* refactor: make processor and prover sync-first APIs

* feat: add async compatibility wrappers for execute and prove

* test: use portable StackInputs construction in async compat tests

* chore: Changelog

* fix: restore no-std build and update README API examples

* docs: add two-step trace doctests and top-level exports

* vm: restore async host execution path

* api: revert rename-only churn

* processor: factor sync and async flow helpers

* docs: trim doctest noise and fix sync examples

* chore: edit CHANGELOG

* prover: add prove-from-trace sync API

* processor: split shared host surface from sync IO

* processor: remove redundant host adapter

* Move fast execution code into execution_api.rs

* Harden trace input bundling

* Preserve trace API compatibility

* Restore trace input constructor compatibility

* Guard compatibility constructor

* Record executed program info in traces

* Protect trace build inputs

* Reject unbound trace input adapters

* Bind compatibility trace inputs to execution context

* Bind trace input adapters to execution outputs

* Bind trace input adapters to advice state

* Make advice fingerprints stable across runs

* Remove execute_sync_mut

* Remove execute_for_trace wrappers

* Return execution output from execute wrappers

* answer review comments

* Polish docs and mark advice fingerprint must-use
* fix(processor): op_u32assert2 no longer ignores the err_code parameter

* fix(processor): use err_code in op_u32assert2 instead of discarding it

Fixes #2844

Previously op_u32assert2 accepted _err_code but never used it, causing
the user-supplied error message/code to be silently ignored when the
assertion fails. This matches the behavior of op_assert which properly
returns FailedAssertion{err_code, err_msg}.

* fix(processor): pass program to op_u32assert2 for error message resolution

Updates the call site to forward current_forest so that op_u32assert2
can resolve the human-readable error message from the err_code.

* fix(processor): correct MastForest import path in op_u32assert2

Use `crate::mast::MastForest` (re-exported from miden_core) rather than
the full external path `miden_core::mast::MastForest`. Also adds the
import to the `use crate` block so the code compiles correctly.

* fix: resolve rustfmt and clippy CI failures

* fix: add missing MastForest argument in op_u32assert2 tests

* fix: rustfmt formatting

* fix: return NotU32Values for out-of-bounds, FailedAssertion for err_code

* fix: err_code propagation in op_u32assert2 — only fail on invalid u32

The previous attempt incorrectly returned FailedAssertion whenever
err_code != 0, even when both stack values were valid u32s.  This
broke every stdlib call-site that passes a non-zero err_code
(e.g. SMT/sorted-array operations), causing unrelated test failures.

Correct logic: only return FailedAssertion (with the err_code) when
at least one value exceeds U32_MAX; succeed normally otherwise.

Also adds two targeted regression tests:
- err_code is propagated into FailedAssertion on invalid input
- valid u32 inputs succeed even when err_code != 0

* fix(processor): return NotU32Values when err_code=0, FailedAssertion when err_code!=0

When op_u32assert2 receives invalid u32 values:
- err_code == 0  -> NotU32Values { values }   (historical default, used by
  u32assert / u32assertw / u32not which internally lower to U32assert2(ZERO))
- err_code != 0  -> FailedAssertion { err_code, err_msg }  (propagate the
  caller-supplied error code so diagnostics can identify the assertion)

The previous fix always returned FailedAssertion { err_code: 0 } which broke
the four integration tests that call u32assert / u32assertw / u32not with
out-of-range values and expect NotU32Values.

Updated unit tests to verify both branches explicitly.

* style: fix nightly rustfmt formatting in tests.rs

* feat(processor): add U32AssertionFailed error variant with invalid value context

Addresses bobbinth's review comment on PR #2894.
Introduces a dedicated OperationError::U32AssertionFailed variant that carries
both the custom err_code/err_msg AND the actual out-of-bounds Felt values that
triggered the assertion failure in op_u32assert2. This gives callers richer
diagnostic context compared to the existing FailedAssertion (which has no value
info) or NotU32Values (which has no err_code).

* refactor(processor): use U32AssertionFailed in op_u32assert2 for richer diagnostics

When err_code != 0 and values are out of u32 range, return the new
U32AssertionFailed variant (instead of FailedAssertion) so the caller
receives both the custom error code/message AND the offending values.
Zero err_code path is unchanged (NotU32Values) for backward compatibility.

* test(processor): update u32assert2 tests for U32AssertionFailed + add assembled-program test

Two changes addressing reviewer feedback on PR #2894:

1. Updated unit tests that previously checked OperationError::FailedAssertion
   to now check OperationError::U32AssertionFailed with the new
   field — confirms both err_code and offending value(s) are present.

2. Added  (addresses huitseeker's
   review request): assembles a MASM program containing ,
   runs it through FastProcessor::execute_sync, and asserts that the resolved
   error message from the MastForest appears in the resulting U32AssertionFailed
   error — verifying the end-to-end execute_op plumbing and message lookup.

* style: fix rustfmt - collapse short assert! to single line in assembled test

* test(processor): add wrapper-level assembled tests for u32assert.err and u32assertw.err

Addresses huitseeker's review request (PR #2894, review 4022230272):
"wrapper-level coverage for u32assert.err / u32assertw.err would still
be worth adding."

Added two new assembled-program integration tests that mirror the
existing test_op_u32assert2_assembled_err_msg_lookup pattern:

- test_u32assert_err_wrapper_assembled:
  Assembles 'push.4294967296 u32assert.err="value must fit in u32"',
  which lowers to [Pad, U32assert2(err_code), Drop].  Verifies that
  U32AssertionFailed is returned with err_msg resolved from the
  MastForest and at least one invalid_value.

- test_u32assertw_err_wrapper_assembled:
  Assembles a word with one out-of-range element and
  'u32assertw.err="word contains non-u32 element"', which lowers to
  two U32assert2(err_code) ops.  Verifies the same end-to-end message
  lookup through execute_sync.

* style: fix rustfmt - inline short assemble_program call in wrapper tests

---------

Co-authored-by: amathxbt <amathxbt@users.noreply.github.com>
Checks each commit in a PR via the GitHub API for signature
verification. Fails the check and posts a remediation comment
when unsigned commits are found.
* fix: reject non-syscall references to exported kernel procedures
Kernel procedures should only be accessible via syscall. The linker was
accepting exec, call, and procref targeting kernel exports. Added a check
in Linker::resolve_invoke_target to reject non-syscall invocations that
resolve to a kernel procedure, while still allowing kernel-internal calls.
Added regression test.
Closes #2902

* fix: reject kernel proc digests on dynexec/dyncall path
Added best-effort static check that detects when the last pushed word
in a basic block matches a kernel procedure digest before dynexec/dyncall.
Replaced single exec test with comprehensive test covering all five
non-syscall routes (exec, call, procref, dynexec, dyncall).
Addresses review feedback on #2903.

* fix: use pub(crate) helper for kernel digest check, fix no-std and nightly fmt

* refactor: drop dynexec/dyncall static kernel check per maintainer review

Removes assembly-time heuristic for dynamic invokes; keeps
Linker::resolve_invoke_target guard for exec/call/procref. Narrows
regression test accordingly.

Addresses review feedback on #2903.

* fix(assembly): enforce syscall-only kernel exports in SymbolResolver

- Move KernelProcNotSyscall guard to SymbolResolver; skip MastRoot/digest invokes; kernel_index + ModuleKind for target/caller
- Thin Linker::resolve_invoke_target wrapper
- processor: cfg_attr(test) allow needless_range_loop; drop stale clippy expects in trace tests

---------

Co-authored-by: crazywriter1 <crazywriter1@users.noreply.github.com>
Co-authored-by: François Garillot <4142+huitseeker@users.noreply.github.com>
Add a note to the enum types section clarifying that enum variants are expanded into module-level constants, and therefore variant names must be unique across all enums and constants within the same module.

Closes #2816

Co-authored-by: Bobbin Threadbare <43513081+bobbinth@users.noreply.github.com>
* refactor: use RowMajorTraceWriter for core trace generation

* refactor: remove core trace transpose and use hybrid MainTrace storage

* refactor: use row-major MainTrace directly in aux trace builder

* perf: optimize row-major trace accessors and conversions

* perf: transpose chiplets to row-major and store them separately

* perf: parallelize to_row_major

* perf: use transposed storage for aux trace builder

* perf: make Aux column building parallel

* chore: update CHANGELOG

* perf: make MainTrace::get safe without hidden bounds checks (#2938)

Replace the flat Parts backing with typed row storage so MainTrace::get() stays fully safe while avoiding compiler-inserted bounds checks on the hot path. Preserve the existing debug layout with borrowing formatters and keep it pinned with a regression test.

* perf: binary search on last row

---------

Co-authored-by: François Garillot <4142+huitseeker@users.noreply.github.com>
* revert: back out MainTrace typed row storage perf regression

* fix: restore MainTrace bounds and shape validation

Restore release-time validation in MainTrace::from_parts() and checked access in MainTrace::get() after the typed row storage revert. This keeps the performance fix while preserving normal panic semantics for malformed trace layouts and out-of-bounds access.

* chore: Changelog

* style: use range checker width constants in MainTrace
Co-authored-by: François Garillot <4142+huitseeker@users.noreply.github.com>
Co-authored-by: François Garillot <4142+huitseeker@users.noreply.github.com>
huitseeker and others added 16 commits April 13, 2026 22:55
…-reconciled-2

Merge main into next (take 2)
Replace the deg-1 `merkle_next_lite = s1' + s2'` indicator with the full
deg-3 `is_merkle_input_next = s0' * (s1' + s2' - s1'*s2')` in the
hasher-controller digest-routing gate. The constraint now sits at
exactly the max degree of 9 (up from 7), trading the remaining headroom
for local soundness: sponge-mislabeling attacks (`s0'=1, s1'=s2'=0`)
are now rejected by the `s0'` factor directly, so no chiplets-bus
label-namespace invariant is required.

Regenerates `RELATION_DIGEST` in `air/src/config.rs` and
`sys/vm/mod.masm`, the ACE circuit description in
`constraints_eval.masm`, and the miden-air insta snapshot.
`num_inputs` (572) and `num_eval_gates` (5580) are unchanged — only
the single affected gate polynomial differs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Snapshot of the uncompressed constraint-equivalence log across the
origin/next merge and the three post-merge refactor commits (periodic
column typing, hasher chiplet split, hasher controller lifetime
restructure). Committed as a trace before lossless compression of
the file for PR comment upload.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…r links

Five sections (#14, #16, #17, #37, #38) each repeat a single narrative
paragraph verbatim across many "Interpretation" cells in their
constraint table. The narrative is already present at the top of each
section, so the table cells are pure duplication.

Add an inline <a id="cN-cat"></a> anchor to each narrative and replace
the duplicate cells with a short link [↑ §N narrative](#cN-cat). Non-
duplicate rows (with per-row-specific interpretations) are untouched.

File size: 88,666 → 43,803 chars. Lossless — the links resolve to the
identical prose. Enables posting the full report as a single GitHub PR
comment under the 65,536-char limit.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Two leftovers from the constraint-simplification work that don't belong
in the merge to next:

- CONSTRAINT_CHANGES.md: developer log of constraint polynomial deltas
  across the refactor. Already archived as PR #2856 issue comment
  4242623244 (the deduped version), which is the authoritative copy.
  Zero code references.

- .constraint-tooling/recorder/degree_builder.rs: debug-only helper for
  tracking polynomial degrees. Its own docstring describes it as scratch
  ("not compiled into the miden-air crate ... revert the edits once
  you're done so the debug-only code doesn't ship"). Zero references in
  the repo; not in any mod.rs or Cargo.toml.

The .gitignore entry for .constraint-tooling/ is kept so future local
runs of the recorder/differ don't dirty the working tree.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add a dedicated HASHER_PERM_LINK bus prefix (bus index 9, NUM_BUS_TYPES
bumped to 10) and route both the AIR perm-link encoder and the
aux-trace builder through `Challenges::encode` instead of the hand-rolled
`alpha + sum(beta^i * h[i])` forms. This was the last bypass of the new
per-bus domain-separation scheme: previously the perm-link messages
shared the `v_wiring` column with ACE wiring and memory range checks but
used bare `alpha`, so label collisions across contributors were
theoretically possible.

Also fixes the stale hasher bus layout docstrings in
`aux_trace/bus/hasher.rs` that described the encoding as
`alpha + <beta, ...>` (per Nashtare review).

Regenerated with `regenerate-constraints --write`: RELATION_DIGEST,
constraints_eval.masm, and the insta snapshot all shift. num_inputs
(572) and num_eval_gates (5580) unchanged - only the additive base of
two v_wiring perm-link sub-expressions moves from `alpha` to
`bus_prefix[HASHER_PERM_LINK]`.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace the post-hoc `for row in 0..bitwise_start` loop deriving
`s_ctrl = 1 - perm_seg` with a single `trace[0][..hasher_ctrl_len].fill(ONE)`
memset, matching how s1..s4 are already populated. The padded controller
length comes from a new `Hasher::region_lengths()` accessor, refactored
out of `estimate_trace_len` so the layout math has a single source of
truth - both callers go through the same
`(ctrl_padded, perm_len)` computation.

The hasher keeps writing `perm_seg` (trace[20]) row-by-row as part of
its existing per-row trace construction; no extra pass. The old loop
walked the entire hasher region doing read-modify-write per row, the
new code is a write-only SIMD-friendly memset over just the controller
prefix.

Also silences a `clippy::needless_range_loop` warning the old form
triggered.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove three unit tests introduced alongside `AceDag::compact()` in
8d259ed. The pass was wiped out in the e875d3d merge from origin/next
(which adopted the new DagBuilder architecture) and never reinstated; the
tests either asserted orphans are kept (contradicting their name) or
referenced a no-longer-existing compaction step. Dropping them makes
unit_tests.rs byte-identical to origin/next.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Fix Falcon remainder validation and u64::rotr overflow handling
adr1anh and others added 6 commits April 16, 2026 11:57
Fix review comments from Al-Kindi-0 and Nashtare on PR #2856:

- Use OpFlags::u32_rc_op() in range bus instead of manual recomputation
- Replace PermutationCols _ fields with private _unused array + accessor
- Add ControllerCols::f_mu/f_mv and AceCols::f_read/f_eval flag methods
- Add last-row boundary constraint enforcing HALT on final decoder row
- Fix comment/doc nits: alignment, terminology, stale references
- Update bus message format comments to use bus_prefix[CHIPLETS_BUS]
- Use assert_eq_ext instead of assert_zero_ext(lhs - rhs)
- Rename (re, im) to (a0, a1) for extension field elements

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Restore semantic detail from the original ace.rs column docs that was
lost during the struct refactor: explain what the ACE chiplet does,
its two-phase operation model (READ/EVAL), the role of multiplicity
columns in the wiring bus, and the physical column aliasing between
READ and EVAL overlays.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix stale `alpha` references in hash_kernel doc comments to `bus_prefix[bus]`
- Rename misleading `alpha` variable to `prefix` in wiring range-check term
- Unify `perm_seg` naming to `s_perm` everywhere (field, constants, methods, docs)
- Add defensive boundary constraint: output at ctrl→perm boundary must be final
  (is_boundary=1), preventing non-final outputs from expecting continuations that
  never come since the next row belongs to the permutation segment

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…mplification

# Conflicts:
#	air/src/constraints/stack/stack_arith/mod.rs
Adapt the Falcon-related u32add/u32sub constraint tests to the
refactored API (MainCols, typed DecoderCols, OpFlags::new signature).
Re-establish the stack_arith/ directory module to host the test file.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…workspace inheritance (#2999)

* Harden GitHub Actions workflows

* Pin cargo-msrv install version

* Scope signed-commit checks to maintainers

* Check workspace dependency inheritance

* Enable std for pretty_assertions in tests

* Remove duplicate changelog status job

* chore: revert eager promotions, be lazier about threshold

* Update contribution quality workflow pin

* Harden recursive constraints workflow
* perf(core): borrow operation slices when batching

* chore(deps): bump rand to 0.9.3 for cargo-deny

* changelog: link basic-block batching entry

---------

Co-authored-by: François Garillot <4142+huitseeker@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.